{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "73637567",
   "metadata": {},
   "source": [
    "函数是一个代码块，它只在被调用时运行。\n",
    "\n",
    "您可以将数据（称为参数）传递给函数。\n",
    "\n",
    "函数可以作为结果返回数据。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c642c7a",
   "metadata": {},
   "source": [
    "# 创建函数\n",
    "在 Python 中，函数是使用 def 关键字定义的："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "18cdb6e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "def my_function():\n",
    "  print(\"Hello from a function\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c0b72068",
   "metadata": {},
   "source": [
    "# 调用函数\n",
    "要调用函数，请使用函数名称后跟括号："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "cb55046a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello from a function\n"
     ]
    }
   ],
   "source": [
    "my_function()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb79d202",
   "metadata": {},
   "source": [
    "# 参数\n",
    "信息可以作为参数传递给函数。\n",
    "\n",
    "参数在函数名后的括号内指定。 您可以根据需要添加任意数量的参数，只需用逗号分隔它们。\n",
    "\n",
    "下面的示例有一个带一个参数 (fname) 的函数。 当函数被调用时，我们传递一个名字，在函数内部使用它来打印全名："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "0bb1b70d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Emil Refsnes\n",
      "Tobias Refsnes\n",
      "Linus Refsnes\n"
     ]
    }
   ],
   "source": [
    "def my_function(fname):\n",
    "  print(fname + \" Refsnes\")\n",
    "\n",
    "my_function(\"Emil\")\n",
    "my_function(\"Tobias\")\n",
    "my_function(\"Linus\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e0bf428",
   "metadata": {},
   "source": [
    "# Parameters or Arguments?\n",
    "术语parameter和arguments可以用于同一件事：传递给函数的信息。\n",
    "\n",
    "从函数的角度来看：\n",
    "\n",
    "parameter是函数定义中括号内列出的变量。\n",
    "\n",
    "arguments参数是在调用函数时发送给函数的值。\n",
    "\n",
    "# 参数数量\n",
    "默认情况下，必须使用正确数量的参数调用函数。 这意味着如果您的函数需要 2 个参数，则必须使用 2 个参数调用该函数，不能多也不能少。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "81bc7548",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Emil Refsnes\n"
     ]
    }
   ],
   "source": [
    "def my_function(fname, lname):\n",
    "  print(fname + \" \" + lname)\n",
    "\n",
    "my_function(\"Emil\", \"Refsnes\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ee795bdd",
   "metadata": {},
   "source": [
    "# 任意参数，*args\n",
    "如果不知道有多少参数将传递到函数中，请在函数定义中的参数名称前添加一个 *。\n",
    "\n",
    "这样，该函数将接收一个参数元组，并可以相应地访问这些项目："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "1deb6ff3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The youngest child is Linus\n"
     ]
    }
   ],
   "source": [
    "def my_function(*kids):\n",
    "  print(\"The youngest child is \" + kids[2])\n",
    "\n",
    "my_function(\"Emil\", \"Tobias\", \"Linus\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37dea2a0",
   "metadata": {},
   "source": [
    "# 关键字参数\n",
    "还可以使用 key = value 语法发送参数。\n",
    "\n",
    "这样，参数的顺序就无关紧要了。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "95d59f57",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The youngest child is Linus\n"
     ]
    }
   ],
   "source": [
    "def my_function(child3, child2, child1):\n",
    "  print(\"The youngest child is \" + child3)\n",
    "\n",
    "my_function(child1 = \"Emil\", child2 = \"Tobias\", child3 = \"Linus\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5cbef0ad",
   "metadata": {},
   "source": [
    "# 任意关键字参数，**kwargs\n",
    "如果不知道有多少关键字参数将被传递到函数中，请在函数定义中的参数名称之前添加两个星号：**。\n",
    "\n",
    "这样，该函数将接收一个参数字典，并可以相应地访问这些项目："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "29422880",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "His last name is Refsnes\n"
     ]
    }
   ],
   "source": [
    "def my_function(**kid):\n",
    "  print(\"His last name is \" + kid[\"lname\"])\n",
    "\n",
    "my_function(fname = \"Tobias\", lname = \"Refsnes\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "570bd033",
   "metadata": {},
   "source": [
    "# 默认参数值\n",
    "以下示例显示如何使用默认参数值。\n",
    "\n",
    "如果我们不带参数调用函数，它使用默认值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "4a6a8d0f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I am from Sweden\n",
      "I am from India\n",
      "I am from Norway\n",
      "I am from Brazil\n"
     ]
    }
   ],
   "source": [
    "def my_function(country = \"Norway\"):\n",
    "  print(\"I am from \" + country)\n",
    "\n",
    "my_function(\"Sweden\")\n",
    "my_function(\"India\")\n",
    "my_function()\n",
    "my_function(\"Brazil\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "06fe01a0",
   "metadata": {},
   "source": [
    "# 将列表作为参数传递\n",
    "可以向函数发送任何数据类型的参数（字符串、数字、列表、字典等），它会在函数内部被视为相同的数据类型。\n",
    "\n",
    "例如。 如果你发送一个 List 作为参数，当它到达函数时它仍然是一个 List："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "94705cc7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "apple\n",
      "banana\n",
      "cherry\n"
     ]
    }
   ],
   "source": [
    "def my_function(food):\n",
    "  for x in food:\n",
    "    print(x)\n",
    "\n",
    "fruits = [\"apple\", \"banana\", \"cherry\"]\n",
    "\n",
    "my_function(fruits)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "856bd830",
   "metadata": {},
   "source": [
    "# 返回值\n",
    "要让函数返回值，请使用 return 语句："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "4eb65e52",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "15\n",
      "25\n",
      "45\n"
     ]
    }
   ],
   "source": [
    "def my_function(x):\n",
    "  return 5 * x\n",
    "\n",
    "print(my_function(3))\n",
    "print(my_function(5))\n",
    "print(my_function(9))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "845733f6",
   "metadata": {},
   "source": [
    "# pass语句\n",
    "函数定义不能为空，但如果由于某种原因有一个没有内容的函数定义，请放入 pass 语句以避免出错。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "db8dad4c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def myfunction():\n",
    "  pass"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ccf32e9c",
   "metadata": {},
   "source": [
    "# 递归\n",
    "Python 也接受函数递归，这意味着定义的函数可以调用自身。\n",
    "\n",
    "递归是一个常见的数学和编程概念。 这意味着函数调用自身。 这意味着您可以遍历数据以得出结果。\n",
    "\n",
    "开发人员应该非常小心递归，因为很容易编写一个永不终止的函数，或者一个使用过多内存或处理器能力的函数。 但是，如果编写正确，递归可能是一种非常有效且数学上优雅的编程方法。\n",
    "\n",
    "在这个例子中，tri_recursion() 是一个我们定义为调用自身的函数（“recurse”）。 我们使用 k 变量作为数据，每次递归都会递减 (-1)。 当条件不大于 0 时（即当它为 0 时）递归结束。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "92844e46",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "Recursion Example Results\n",
      "1\n",
      "3\n",
      "6\n",
      "10\n",
      "15\n",
      "21\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "21"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def tri_recursion(k):\n",
    "  if(k > 0):\n",
    "    result = k + tri_recursion(k - 1)\n",
    "    print(result)\n",
    "  else:\n",
    "    result = 0\n",
    "  return result\n",
    "\n",
    "print(\"\\n\\nRecursion Example Results\")\n",
    "tri_recursion(6)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.10"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
